cmake_minimum_required(VERSION 3.16.0)
SET(CMAKE_COLOR_MAKEFILE ON)
#POLICIES
CMAKE_POLICY (SET CMP0048 NEW)
CMAKE_POLICY (SET CMP0053 NEW)
CMAKE_POLICY (SET CMP0071 NEW)
CMAKE_POLICY (SET CMP0079 NEW)
if(POLICY CMP0091)
    cmake_policy(SET CMP0091 NEW)
endif()
## https://cmake.org/cmake/help/latest/policy/CMP0135.html
# CMAKE_POLICY (SET CMP0135 NEW)

set(MS_VERSION 1.0.0)
project(mediasoup-cpp VERSION ${MS_VERSION})
message(STATUS "Build mediasoup: ${MS_VERSION}")

# C++ standard requirements.
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

#加载自定义模块
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

include(CheckIncludeFile)
include(CheckFunctionExists)
include(CheckLibraryExists)
INCLUDE (CheckCSourceCompiles)

#include(cmake/asan.cmake)


find_program(CCACHE_FOUND ccache)
if(CCACHE_FOUND)
    set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
    set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK    ccache)
endif()

if(UNIX)
    #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
    #    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address  -fsanitize-recover=address -fno-stack-protector -fno-omit-frame-pointer")
    # UNIX/Linux/Darwin
    set(COMPILE_OPTIONS_DEFAULT
            "-fPIC"
            "-Wall;-Wextra"
            "-Wno-unused-function;-Wno-unused-parameter;-Wno-unused-variable"
            "-Wno-error=extra;-Wno-error=missing-field-initializers;-Wno-error=type-limits")
elseif(WIN32)
    if (MSVC)
        set(COMPILE_OPTIONS_DEFAULT
                # TODO: /wd4819 应该是不会生效
                "/wd4566;/wd4819"
                # warning C4530: C++ exception handler used, but unwind semantics are not enabled.
                "/EHsc")
        # disable Windows logo
        list(APPEND COMPILE_OPTIONS_DEFAULT "/nologo")
        list(APPEND CMAKE_STATIC_LINKER_FLAGS "/nologo")
    endif()
endif()

if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
    if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64")
        include_directories(SYSTEM "/opt/homebrew/include")
    endif()
endif()

# 方便修改全局变量
function(update_cached name value)
    set("${name}" "${value}" CACHE INTERNAL "*** Internal ***" FORCE)
endfunction()

function(update_cached_list name)
    set(_tmp_list "${${name}}")
    list(APPEND _tmp_list "${ARGN}")
    list(REMOVE_DUPLICATES _tmp_list)
    update_cached(${name} "${_tmp_list}")
endfunction()

# TODO:
function(set_file_group prefix)
    message(STATUS "set_file_group " ${prefix} " " ${ARGC})
    foreach(FILE IN LISTS ARGN 1)
        # Get the directory of the source file
        get_filename_component(PARENT_DIR "${FILE}" DIRECTORY)

        # Remove common directory prefix to make the group
        string(REPLACE "${prefix}" "" GROUP "${PARENT_DIR}")

        # Make sure we are using windows slashes
        string(REPLACE "/" "\\" GROUP "${GROUP}")

        source_group("${GROUP}" FILES "${FILE}")
    endforeach()
endfunction()

#set(CMAKE_BUILD_TYPE "Release")
message(STATUS "编译类型:${CMAKE_BUILD_TYPE}")

#设置bin和lib库目录
set(RELEASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/release)

if (CMAKE_SYSTEM_NAME MATCHES "Linux")
    SET(LIBRARY_OUTPUT_PATH ${RELEASE_DIR}/linux/${CMAKE_BUILD_TYPE})
    SET(EXECUTABLE_OUTPUT_PATH ${RELEASE_DIR}/linux/${CMAKE_BUILD_TYPE})
    add_compile_options(-fPIC -Wall -Wno-unused-variable -Wno-unused-value)
    INCLUDE(CheckCXXSourceCompiles)
    file(READ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/checks/atomic_check.cpp atomic_check_cpp)
    CHECK_CXX_SOURCE_COMPILES("${atomic_check_cpp}" HAVE_CXX_ATOMICS_WITHOUT_LIB)
    if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB)
        list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
        CHECK_CXX_SOURCE_COMPILES("${atomic_check_cpp}" HAVE_CXX_ATOMICS_WITH_LIB)
        if(NOT HAVE_CXX_ATOMICS_WITH_LIB)
            message(WARNING "Compiler doesn't support std::atomic<long long>")
        else()
            set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -latomic")
        endif()
    endif()
elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")
    #    if (CMAKE_CL_64)
    #        set(CL_32_64 64)
    #    else ()
    #        set(CL_32_64 32)
    #    endif ()
    SET(LIBRARY_OUTPUT_PATH ${RELEASE_DIR}/windows${CL_32_64}/${CMAKE_BUILD_TYPE})
    SET(EXECUTABLE_OUTPUT_PATH ${RELEASE_DIR}/windows${CL_32_64}/${CMAKE_BUILD_TYPE})
elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
    SET(LIBRARY_OUTPUT_PATH ${RELEASE_DIR}/mac/${CMAKE_BUILD_TYPE})
    SET(EXECUTABLE_OUTPUT_PATH ${RELEASE_DIR}/mac/${CMAKE_BUILD_TYPE})
    add_compile_options(-Wall -Wno-unused-variable -Wno-unused-value)
endif ()

LINK_DIRECTORIES(${LIBRARY_OUTPUT_PATH})

set(DEBUG_LEVEL DEBUG_LEVEL_INFO)

set(LIB_TYPE SHARED)

if (MSVC AND ENABLE_MSVC_MT)
    set(CompilerFlags
            CMAKE_CXX_FLAGS
            CMAKE_CXX_FLAGS_DEBUG
            CMAKE_CXX_FLAGS_RELEASE
            CMAKE_C_FLAGS
            CMAKE_C_FLAGS_DEBUG
            CMAKE_C_FLAGS_RELEASE
    )
    foreach(CompilerFlag ${CompilerFlags})
        string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}")
    endforeach()
endif()

if (${BUILD_LIB_STATIC})
    set(LIB_TYPE STATIC)
    message(STATUS "Build module as static lib")
    if (MSVC)
        ## 去掉 VCRUNTIME 依赖
        add_compile_options(/MT$<$<CONFIG:Debug>:d>)
    elseif(NOT ANDROID AND NOT IOS)
        set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-Bsymbolic")
    endif ()
else()
    set(LIB_TYPE SHARED)
    message(STATUS "Build module as shared lib")
    if (MSVC)
        ## 去掉 VCRUNTIME 依赖
        add_compile_options(/MT$<$<CONFIG:Debug>:d>)
    endif()
endif ()

set(subModules 3rdpart)

foreach (mod ${subModules})
    add_subdirectory(${mod})
endforeach ()

## 模块分组
# ----------------------------------------------------------------------------
# Solution folders:
# ----------------------------------------------------------------------------
if(USE_SOLUTION_FOLDERS)
    set_property(GLOBAL PROPERTY USE_FOLDERS ON)
    set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMakeTargets")
endif()

function(set_file_group prefix)
    message(STATUS "set_file_group " ${prefix} " " ${ARGC})
    foreach(FILE IN LISTS ARGN 1)
        # Get the directory of the source file
        get_filename_component(PARENT_DIR "${FILE}" DIRECTORY)

        # Remove common directory prefix to make the group
        string(REPLACE "${prefix}" "" GROUP "${PARENT_DIR}")

        # Make sure we are using windows slashes
        string(REPLACE "/" "\\" GROUP "${GROUP}")

        # Group into "Source Files" and "Header Files"
        #if ("${FILE}" MATCHES ".*\\.cpp")
        #   set(GROUP "Source Files${GROUP}")
        #elseif("${FILE}" MATCHES ".*\\.h")
        #   set(GROUP "Header Files${GROUP}")
        #endif()
        #message(STATUS ${GROUP} " : " ${FILE})
        source_group("${GROUP}" FILES "${FILE}")
    endforeach()
endfunction()



add_subdirectory(src)